package org.thirdeyetvg.ncanreader.helper;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.thirdeyetvg.ncanreader.constants.LocalConstants;

import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.Layout.Alignment;
import android.util.Log;
import android.widget.TextView;

public class TextReaderUtil {

	static int startIndexOfCurrentPage = 0;
	static int startIndexOfNextPage = 0;

	StringBuffer strBuff;
	private TextView tv;

	public TextReaderUtil(String text, TextView tv) {
		strBuff = new StringBuffer(text);
		this.tv = tv;
	}

	public TextReaderUtil(FileInputStream fstream, TextView tv)
			throws IOException {
		DataInputStream in = new DataInputStream(fstream);
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		strBuff = new StringBuffer();
		String strLine;
		while ((strLine = br.readLine()) != null) {
			strBuff.append(strLine + "\n");
		}
		in.close();
		this.tv = tv;
	}

	public TextReaderUtil(InputStream open, TextView tv) throws IOException {
		this.tv = tv;
		BufferedReader reader = new BufferedReader(new InputStreamReader(open));
		String line = reader.readLine();
		strBuff = new StringBuffer();
		while (line != null) {
			strBuff.append(line + "\n");
			line = reader.readLine();
		}
		reader.close();
	}

	public String nextPage() {
		int contentFitness = 0;
		int actualIndex = startIndexOfNextPage;
		String stringToFind = "\n";
		boolean isLineNav = true;
		while (true) {
			int tempIndex = getTextTillNextStr(actualIndex, stringToFind);
			if (tempIndex == -1) {
				break;
			}
			String content = strBuff.substring(startIndexOfNextPage, tempIndex);
			contentFitness = checkIfContentFits(content);
			if (contentFitness == LocalConstants.TEXT_EXCEEDS) {
				if (isLineNav) {
					isLineNav = false;
					stringToFind = " ";
				} else {
					break;
				}
			} else {
				actualIndex = tempIndex;
				if (contentFitness == LocalConstants.TEXT_FITS_EXACTLY) {
					break;
				}
			}
		}
		String content = null;
		if (actualIndex != startIndexOfNextPage) {
			content = strBuff.substring(startIndexOfNextPage, actualIndex);
			startIndexOfCurrentPage = startIndexOfNextPage;
			startIndexOfNextPage = actualIndex;
		}
		return content;
	}

	private int getTextTillNextStr(int startIndex, String str) {
		int nextSpaceIndex = -1;
		int length = strBuff.length();
		if (startIndex < length) {
			nextSpaceIndex = strBuff.indexOf(str, startIndex + 1);
			// If no newLine found, return length
			if (nextSpaceIndex == -1) {
				nextSpaceIndex = length;
			}
		}
		return nextSpaceIndex;
	}

	public String previousPage() {
		int contentFitness = 0;
		int actualIndex = startIndexOfCurrentPage;
		String stringToFind = "\n";
		boolean isLineNav = true;
		while (true) {
			int tempIndex = getTextTillPrevStr(actualIndex, stringToFind);
			if (tempIndex == -1) {
				break;
			}
			String content = strBuff.substring(tempIndex,
					startIndexOfCurrentPage);
			contentFitness = checkIfContentFits(content);
			if (contentFitness == LocalConstants.TEXT_EXCEEDS) {
				if (isLineNav) {
					isLineNav = false;
					stringToFind = " ";
				} else {
					break;
				}
			} else {
				actualIndex = tempIndex;
				if (contentFitness == LocalConstants.TEXT_FITS_EXACTLY) {
					break;
				}
			}
		}
		String content = null;
		if (actualIndex != startIndexOfCurrentPage) {
			content = strBuff.substring(actualIndex, startIndexOfCurrentPage);
			startIndexOfNextPage = startIndexOfCurrentPage;
			startIndexOfCurrentPage = actualIndex;
		}
		return content;
	}

	private int getTextTillPrevStr(int startIndex, String str) {
		int nextSpaceIndex = -1;
		if (startIndex > 0) {
			nextSpaceIndex = strBuff.lastIndexOf(str, startIndex - 1);
			// If no newLine found, return length
			if (nextSpaceIndex == -1) {
				nextSpaceIndex = 0;
			} else {
				if (" ".equalsIgnoreCase(str)) {
					int nextNewLineIndex = strBuff.lastIndexOf(str,
							startIndex - 1);
					if (nextNewLineIndex > nextSpaceIndex) {
						nextSpaceIndex = nextNewLineIndex;
					}
				}
			}
		}
		return nextSpaceIndex;
	}

	private int checkIfContentFits(String content) {
		int textViewHeight = tv.getHeight();
		int textViewWidth = tv.getWidth();
		TextPaint paint = tv.getPaint();
		int currentTextViewContentHeight = getTextHeight(content, paint,
				textViewWidth, 1, 0);

		Log.d("", "currentTextViewContentHeight:"
				+ currentTextViewContentHeight);
		int contentLength = content.length();
		Log.d("", "contentLength:" + contentLength);
		// System.out.println("Content Length:" + contentLength);
		if (currentTextViewContentHeight > textViewHeight) {
			// System.out.println("Content exceeds.");
			return LocalConstants.TEXT_EXCEEDS;
		} else if (currentTextViewContentHeight < textViewHeight) {
			// System.out.println("Content can contain more.");
			return LocalConstants.CAN_CONTAIN_MORE_TEXT;
		}
		// System.out.println("Content fits.");
		return LocalConstants.TEXT_FITS_EXACTLY;
	}

	private int getTextHeight(CharSequence source, TextPaint paint, int width,
			float mSpacingMult, float mSpacingAdd) {
		// Measure using a static layout
		StaticLayout layout = new StaticLayout(source, paint, width,
				Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true);
		return layout.getHeight();
	}
}
